@file:OptIn(ExperimentalForeignApi::class)

package com.tencent.compose.utils

import androidx.compose.ui.napi.JsEnv
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.NativePtr
import kotlinx.cinterop.alloc
import kotlinx.cinterop.interpretCPointer
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.ptr
import kotlinx.cinterop.value
import platform.ohos.napi_create_array_with_length
import platform.ohos.napi_env
import platform.ohos.napi_value
import platform.ohos.napi_valueVar
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlin.time.Instant

@OptIn(ExperimentalForeignApi::class)
fun napi_value.asString(): String? {
    return napi_get_kotlin_string_utf16(JsEnv.env().rawValue, this.rawValue)
}

fun napi_value.asStringUtf8(): String? {
    return JsEnv.getValueStringUtf8(this)
}

fun createString(value: String): napi_value? {
    val nativePtr: NativePtr = JsEnv.env().rawValue
    val result: napi_value? = interpretCPointer(value.getNapiValue(nativePtr))
//    val str1 = result.asString()
//    val str2 = result?.asStringUtf8()
//    println("kn: result.asString     length=${str1?.length}, result=${str1}, charArray=${toPrintChar(str1)}")
//    println("kn: result.asStringUtf8 length=${str2?.length}, result=${str2}, charArray=${toPrintChar(str2)}")
    return result
}

fun toPrintChar(asString: String?): List<String>? {
    return asString?.split("")?.map { item -> "(${item.length},${item})" }
}

fun getElementInArray(env: napi_env?, value: napi_value?, index: Int): napi_value? {
    val res: napi_value? = JsEnv.getElement(value, index)
    return res
}

fun setElementInArray(env: napi_env?, array: napi_value?, index: Int, value: napi_value?) {
    JsEnv.setElement(array, index, value)
}

fun createArrayWithLength(env: napi_env?, length: Int) : napi_value? {
    return memScoped {
        val result = alloc<napi_valueVar>()
//        napi_create_array(env, result.ptr)
        napi_create_array_with_length(env, length.toULong(), result.ptr)
        result.value
    }
}

@OptIn(ExperimentalTime::class)
fun calcTime(tag: String, time: Instant) {
    val now = Clock.System.now()
    val diff = now.minus(time).inWholeNanoseconds
    println("$tag, time=${time.nanosecondsOfSecond}, now=${now.nanosecondsOfSecond}, diff=$diff ns")
}
